/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "timeline_rdb_manager.h"
#include <string>
#include <cerrno>
#include <sys/epoll.h>
#include <sys/timerfd.h>
#include <linux/netlink.h>
#include <unistd.h>
#include <time.h>
#include "dummy_values_bucket.h"
#include "timeline_database_info.h"
#include "power_mgr_client.h"
#include "power_state_machine_info.h"
#include "battery_srv_client.h"
#include "battery_info.h"
#include "datetime_ex.h"
#include "timeline_common.h"

using namespace OHOS::NativeRdb;
namespace OHOS {
namespace Msdp {
namespace {
const int TIMER_INTERVAL_AWAK = 10;
const int TIMER_INTERVAL_INACTIVE = 600;
const int TIMER_INTERVAL_SLEEP = 1200;
const int ERR_INVALID_FD = -1;
const int IGRONE_TIME = 5;
const int TIMER_SLEEP_TIME = 30;
const std::string DATABASE_NAME = "/data/MsdpStub.db";
const std::string SCHEDULE_TABLE_NAME = "TIMELINESCHEDULE";
const std::string SCHEDULE_CREATE_TABLE = std::string("CREATE TABLE IF NOT EXISTS TIMELINESCHEDULE ") +
    std::string("(ID INTEGER PRIMARY KEY AUTOINCREMENT, MOVEMENT_TYPE INTEGER, LONGITUDE REAL, LATITUDE REAL, STARTTIMEYEAR INTEGER, STARTTIMEMONTH INTEGER, STARTTIMEDAY INTEGER, STARTTIMEHOUR INTEGER, STARTTIMEMIN INTEGER, STARTTIMESEC INTEGER, ENDTIMEYEAR INTEGER, ENDTIMEMONTH INTEGER, ENDTIMEDAY INTEGER, ENDTIMEHOUR INTEGER, ENDTIMEMIN INTEGER, ENDTIMESEC INTEGER, SSID TEXT, BSSID TEXT)");
const std::string STAY_TABLE_NAME = "TIMELINELISTTABLE";
const std::string STAY_CREATE_TABLE = std::string("CREATE TABLE IF NOT EXISTS TIMELINELISTTABLE ") +
    std::string("(ID INTEGER PRIMARY KEY AUTOINCREMENT, LONGITUDE REAL, LATITUDE REAL, STARTTIMEYEAR INTEGER, STARTTIMEMONTH INTEGER, STARTTIMEDAY INTEGER, STARTTIMEHOUR INTEGER, STARTTIMEMIN INTEGER, STARTTIMESEC INTEGER, ENDTIMEYEAR INTEGER, ENDTIMEMONTH INTEGER, ENDTIMEDAY REAL, ENDTIMEHOUR INTEGER, ENDTIMEMIN INTEGER, ENDTIMESEC INTEGER, SSID TEXT, BSSID TEXT)");
std::unique_ptr<TimelineRdbManager> timelineRdbMgr_ = std::make_unique<TimelineRdbManager>();
int i = 0;
int j = 0;
}

bool TimelineRdbManager::Init()
{
    InitRdbStore();
    InitScheduleRdbStore();
    InitAwakeTimer();
    InitInactiveTimer();
    InitSleepTimer();
    StartThread();
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "TimelineRdbInit: exit");
    return true;
}

void TimelineRdbManager::InitRdbStore()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    int errCode = ERR_OK;
    RdbStoreConfig config(DATABASE_NAME);
    InsertOpenCallback helper;
    store_ = RdbHelper::GetRdbStore(config, 1, helper, errCode);

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
}

void TimelineRdbManager::GetListMap(TimelineDatabaseMap &dataListMap)
{
    {
        std::unique_lock<std::mutex> lock(mutex_);
        dataListMap = listDataMap_;
    }
}

void TimelineRdbManager::GetRdbMap(MovementDataMap &movementDataMap)
{
    {
        std::unique_lock<std::mutex> lock(mutex_);
        movementDataMap = rdbDataMap_;
        TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "GetRdbMap: size is : %{public}d", rdbDataMap_.size());
    }
}

ErrCode TimelineRdbManager::Register(CallbackImpl callback)
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    callbacksImpl_ = callback;
    return ERR_OK;
}

ErrCode TimelineRdbManager::Unregister() const
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    return ERR_OK;
}

ErrCode TimelineRdbManager::Enable()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "Exit");
    return ERR_OK;
}

ErrCode TimelineRdbManager::Disable()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "Exit");
    return ERR_OK;
}


ErrCode TimelineRdbManager::NotifyMsdpImpl(TimelineDataUtils::TimelineData& data)
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    callbacksImpl_(data);

    return ERR_OK;
}

int TimelineRdbManager::TrigerDatabaseObserver()
{
     TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    int columnIndex;
    int intVal;
    double dVal;
    std::string strVal;
    std::string str;

    if (store_ == nullptr) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "store_ is not exist");
        sleep(TIMER_SLEEP_TIME);
        InitRdbStore();
        return -1;
    }

    std::unique_ptr<ResultSet> resultSet =
        store_->QuerySql("SELECT * FROM TIMELINE WHERE ID = (SELECT max(ID) from TIMELINE)");
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "Get table success");

    if (resultSet == nullptr) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "database is not exist");
        sleep(TIMER_SLEEP_TIME);
        return -1;
    }

    int ret = resultSet->GoToFirstRow();
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "GoToFirstRow wrong");
        sleep(TIMER_SLEEP_TIME);
        return -1;
    }

    ret = resultSet->GetColumnIndex("ID", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckID: GetColumnIndex failed");
        sleep(TIMER_SLEEP_TIME);
        return -1;
    }
    ret = resultSet->GetInt(columnIndex, intVal);
    if (ret != ERR_OK) {
        return -1;
    }
    
    //get timeline type
    ret = resultSet->GetColumnIndex("MOVEMENT_TYPE", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckMovementType: GetColumnIndex failed");
        return -1;
    }
    ret = resultSet->GetInt(columnIndex, intVal);
    MovementType_ = intVal;
    
    if (ret != ERR_OK) {
        return -1;
    }

    //get Time Stamp
    ret = resultSet->GetColumnIndex("TIME_STAMP", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckTimeStamp: GetColumnIndex failed");
        return -1;
    }
    ret = resultSet->GetDouble(columnIndex, dVal);
    TimeStamp_ = dVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get longitude
    ret = resultSet->GetColumnIndex("LONGITUDE", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckLongitude: GetColumnIndex failed");
        return -1;
    }
    ret = resultSet->GetDouble(columnIndex, dVal);
    Longitude_ = dVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get latitude
    ret = resultSet->GetColumnIndex("LATITUDE", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckLatitude: GetColumnIndex failed");
        return -1;
    }
    ret = resultSet->GetDouble(columnIndex, dVal);
    Latitude_ = dVal;
    if (ret != ERR_OK) {
        return -1;
    }
    
    //get ssid
    ret = resultSet->GetColumnIndex("SSID", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "Checkssid: GetColumnIndex failed");
        return -1;
    }
    ret = resultSet->GetString(columnIndex, strVal);
    SSID_= strVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get Bssid
    ret = resultSet->GetColumnIndex("BSSID", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "Checkbssid: GetColumnIndex failed");
        return -1;
    }
    ret = resultSet->GetString(columnIndex, strVal);
    BSSID_= strVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get DevicestatusType
    ret = resultSet->GetColumnIndex("DEVICESTATUS_TYPE", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckDevicestatusType: GetColumnIndex failed");
        return -1;
    }
    ret = resultSet->GetInt(columnIndex, intVal);
    DevicestatusType_ = intVal;
    
    if (ret != ERR_OK) {
        return -1;
    }

    ret = resultSet->Close();
    if (ret != ERR_OK) {
        return -1;
    }
    
    lbsData.MOVEMENT_TYPE = MovementType_;
    lbsData.MOVEMENT_STATUS = MovementStatus_;
    lbsData.TIME_STAMP = TimeStamp_;
    lbsData.LONGITUDE = Longitude_;
    lbsData.LATITUDE = Latitude_;
    lbsData.SSID = SSID_;
    lbsData.BSSID = BSSID_;
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ScheduleRdbdataInsert:  lbsData: %{public}d, %{public}d, %{public}f, %{public}f, %{public}s, %{public}s", lbsData.MOVEMENT_TYPE, lbsData.TIME_STAMP, lbsData.LONGITUDE,lbsData.LATITUDE, lbsData.SSID.c_str(), lbsData.BSSID.c_str());
    SaveRdbData(lbsData);
    ScheduleRdbdataInsert(lbsData);

    return columnIndex;
}


void TimelineRdbManager::InitAwakeTimer()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    epFd_ = epoll_create1(EPOLL_CLOEXEC);
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "epFd_: %{public}d", epFd_);
    if (epFd_ == -1) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "create epoll fd fail.");
    }
    awakeTimerFd_ = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "awakeTimerFd_: %{public}d", awakeTimerFd_);
    if (awakeTimerFd_ == ERR_INVALID_FD) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "create timer fd fail.");
    }
    SetTimerInterval(TIMER_INTERVAL_AWAK);
    fcntl(awakeTimerFd_, F_SETFL, O_NONBLOCK);
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "start callback");
    callbacks_.insert(std::make_pair(awakeTimerFd_, &TimelineRdbManager::AwakeTimerCallback));
    if (RegisterTimerCallback(awakeTimerFd_, EVENT_TIMER_FD)) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "register timer fd fail.");
    }
}

void TimelineRdbManager::AwakeTimerCallback()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    unsigned long long timers;
    if (read(awakeTimerFd_, &timers, sizeof(timers)) == -1) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "read timer fd fail.");
        return;
    }
    PowerMgr::PowerState ret = PowerMgr::PowerMgrClient::GetInstance().GetState();
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "PowerState: %{public}d", ret);
    if (ret !=PowerMgr::PowerState::AWAKE){
        TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "Not Awaek");
        return;
    }
    TrigerDatabaseObserver();
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
}

void TimelineRdbManager::InitInactiveTimer()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");

    inactiveTimerFd_ = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "inactiveTimerFd_: %{public}d", inactiveTimerFd_);
    if (inactiveTimerFd_ == ERR_INVALID_FD) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "create timer fd fail.");
    }
    SetTimerInterval(TIMER_INTERVAL_INACTIVE);
    fcntl(inactiveTimerFd_, F_SETFL, O_NONBLOCK);
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "start callback");
    callbacks_.insert(std::make_pair(inactiveTimerFd_, &TimelineRdbManager::InactiveTimerCallback));
    if (RegisterTimerCallback(inactiveTimerFd_, EVENT_TIMER_FD)) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "register timer fd fail.");
    }
}

void TimelineRdbManager::InactiveTimerCallback()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    unsigned long long timers;
    if (read(inactiveTimerFd_, &timers, sizeof(timers)) == -1) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "read timer fd fail.");
        return;
    }
    PowerMgr::PowerState ret = PowerMgr::PowerMgrClient::GetInstance().GetState();
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "PowerState: %{public}d", ret);
    if (ret !=PowerMgr::PowerState::INACTIVE){
        TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "Not Inactive");
        return;
    }
    TrigerDatabaseObserver();
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
}

void TimelineRdbManager::InitSleepTimer()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");

    sleepTimerFd_ = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "sleepTimerFd_: %{public}d", sleepTimerFd_);
    if (sleepTimerFd_ == ERR_INVALID_FD) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "create timer fd fail.");
    }
    SetTimerInterval(TIMER_INTERVAL_SLEEP);
    fcntl(sleepTimerFd_, F_SETFL, O_NONBLOCK);
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "start callback");
    callbacks_.insert(std::make_pair(sleepTimerFd_, &TimelineRdbManager::SleepTimerCallback));
    if (RegisterTimerCallback(sleepTimerFd_, EVENT_TIMER_FD)) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "register timer fd fail.");
    }
}

void TimelineRdbManager::SleepTimerCallback()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    unsigned long long timers;
    int SLEEP_TIME = sleeptime_;
    int WAKEUP_TIME = wakeuptime_;
    if (read(sleepTimerFd_, &timers, sizeof(timers)) == -1) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "read timer fd fail.");
        return;
    }
    PowerMgr::PowerState ret = PowerMgr::PowerMgrClient::GetInstance().GetState();
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "PowerState: %{public}d", ret);
    if (ret !=PowerMgr::PowerState::SLEEP){
        TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "Not Sleep");
        return;
    }
    struct tm time = {0};
    if (!GetSystemCurrentTime(&time)) {
        return;
    }
    PowerMgr::BatteryPluggedType batterchargetype_ = PowerMgr::BatterySrvClient::GetInstance().GetPluggedType();
    if ((batterchargetype_ == PowerMgr::BatteryPluggedType::PLUGGED_TYPE_NONE ||
        batterchargetype_ != PowerMgr::BatteryPluggedType::PLUGGED_TYPE_BUTT) ) {
        if (time.tm_hour>SLEEP_TIME ||time.tm_hour < WAKEUP_TIME) {
            TrigerDatabaseObserver();
            if (DevicestatusType_ == TimelineDatabaseInfo::DevicestatusType::TYPE_FINE_STILL) {
                TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "During sleep and plug");
                ScheduleRdbdataInsert(lbsData);
            }
        }
    } else {
        TrigerDatabaseObserver();
    }
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
}

void TimelineRdbManager::SetTimerInterval(int interval)
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    struct itimerspec itval;

   if (awakeTimerFd_ == ERR_INVALID_FD) {
        return;
    }
   if (inactiveTimerFd_ == ERR_INVALID_FD) {
        return;
    }
    if (sleepTimerFd_ == ERR_INVALID_FD) {
        return;
    }

    timerInterval_ = interval;

    if (interval < 0) {
        interval = 0;
    }

    itval.it_interval.tv_sec = interval;
    itval.it_interval.tv_nsec = 0;
    itval.it_value.tv_sec = interval;
    itval.it_value.tv_nsec = 0;

    if (timerfd_settime(awakeTimerFd_, 0, &itval, nullptr) == -1) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "set timer failed");
    }
    if (timerfd_settime(inactiveTimerFd_, 0, &itval, nullptr) == -1) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "set timer failed");
    }
    if (timerfd_settime(sleepTimerFd_, 0, &itval, nullptr) == -1) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "set timer failed");
    }

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
    return;
}

void TimelineRdbManager::TimerCallback()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    unsigned long long timers;
    if (read(awakeTimerFd_, &timers, sizeof(timers)) == -1) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "read timer fd fail.");
        return;
    }
    if (read(inactiveTimerFd_, &timers, sizeof(timers)) == -1) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "read timer fd fail.");
        return;
    }
    if (read(sleepTimerFd_, &timers, sizeof(timers)) == -1) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "read timer fd fail.");
        return;
    }
    TrigerDatabaseObserver();
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
}

int TimelineRdbManager::RegisterTimerCallback(const int fd, const EventType et)
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    struct epoll_event ev;

    ev.events = EPOLLIN;
    if (et == EVENT_TIMER_FD) {
        ev.events |= EPOLLWAKEUP;
    }

    ev.data.ptr = reinterpret_cast<void*>(this);
    ev.data.fd = fd;
    if (epoll_ctl(epFd_, EPOLL_CTL_ADD, fd, &ev) == -1) {
        TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "epoll_ctl failed, error num =%{public}d", errno);
        return -1;
    }

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
    return 0;
}

void TimelineRdbManager::StartThread()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    std::make_unique<std::thread>(&TimelineRdbManager::LoopingThreadEntry, this)->detach();
}

void TimelineRdbManager::LoopingThreadEntry()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    int nevents = 0;
    size_t cbct = callbacks_.size();
    struct epoll_event events[cbct];

    while (true) {
        int timeout = 0;

        nevents = epoll_wait(epFd_, events, cbct, timeout);
        if (nevents == -1) {
            TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "nevents == -1)");
            continue;
        }
        for (int n = 0; n < nevents; ++n) {
            TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "start event");
            TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "nevents: %{public}d", nevents);
            if (events[n].data.ptr) {
                TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "get data");
                TimelineRdbManager *func = const_cast<TimelineRdbManager *>(this);
                TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "events[n].data.ptr: %{public}d", events[n].data.u32);
                (callbacks_.find(events[n].data.fd)->second)(func);
            }
        }
    }
}

TimelineDatabaseInfo::MovementData TimelineRdbManager::SaveRdbData(TimelineDatabaseInfo::MovementData& MovementData)
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    rdbId += 1;
    rdbDataMap_.insert(std::make_pair(rdbId, MovementData));
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "SaveRdbData: size is : %{public}d", rdbDataMap_.size());
    return MovementData;
}

bool TimelineRdbManager::UpdateSleepTime(int32_t sleeptime, int32_t wakeuptime)
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "UpdatePositionState: fun is start");
    sleeptime_ = sleeptime;
    wakeuptime_ = wakeuptime;
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "area is : %{public}d", sleeptime_);
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "area is : %{public}d", wakeuptime_);
    return true;
}

uint32_t TimelineRdbManager::GetSleepTime() 
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "sleeptime is : %{public}d", sleeptime_);
    return sleeptime_;
}

uint32_t TimelineRdbManager::GetWakeupTime() 
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "wakeuptime is : %{public}d", wakeuptime_);
    return wakeuptime_;
}

ErrCode TimelineInterface::Enable()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    if (timelineRdbMgr_ == nullptr) {
        timelineRdbMgr_ = std::make_unique<TimelineRdbManager>();
    }

    timelineRdbMgr_->Init();

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "Exit");
    return ERR_OK;
}

ErrCode TimelineInterface::Disable()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    timelineRdbMgr_->Disable();

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "Exit");
    return ERR_OK;
}

ErrCode TimelineInterface::RegisterCallback(CallbackImpl callback)
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    timelineRdbMgr_->Register(callback);

    return ERR_OK;
}

ErrCode TimelineInterface::UnregisterCallback() const
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    timelineRdbMgr_->Unregister();

    return ERR_OK;
}

void TimelineRdbManager::InitScheduleRdbStore()
{
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "InitScheduleRdbStore: enter");
    int errCode = ERR_OK;
    // ValuesBucket scheduleValues;
    RdbStoreConfig config(DATABASE_NAME);
    InsertOpenCallback helper;
    scheduleStore_ = RdbHelper::GetRdbStore(config, 1, helper, errCode);
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "InitScheduleRdbStore: exit");
}

int32_t TimelineRdbManager::ScheduleRdbdataInsert(TimelineDatabaseInfo::MovementData& movementData)
{
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ScheduleRdbdataInsert: enter");
    // int errCode = ERR_OK;
    int64_t id;
    // int i = 0;
    // int j = 0;
    
    ValuesBucket scheduleValues;
    int ret = -1;
    ret = scheduleStore_->ExecuteSql(SCHEDULE_CREATE_TABLE);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "ScheduleRdbdataInsert: failed to create table");
        return ret;
    }
    if (i == 0) {
        movementTempDataOne = movementData;
        i++;
    } else {
        movementTempDataTwo = movementData;
        i--;
    }
    if (movementTempDataTwo.LONGITUDE == -1000) {
        TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ScheduleRdbdataInsert:  Need second data");
        return 0;
    }
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ScheduleRdbdataInsert:  get data for scheduleTemp");
    if (j == 0) {
        if (i == 1) {
            scheduleTempOne.START_TIME = timelinedatabaseinfo_->getTime(movementTempDataTwo.TIME_STAMP);
            scheduleTempOne.END_TIME = timelinedatabaseinfo_->getTime(movementTempDataOne.TIME_STAMP);
            scheduleTempOne.LATITUDE = movementTempDataTwo.LATITUDE;
            scheduleTempOne.LONGITUDE = movementTempDataTwo.LONGITUDE;
            scheduleTempOne.MOVEMENT_TYPE= movementTempDataTwo.MOVEMENT_TYPE;
            scheduleTempOne.SSID = movementTempDataTwo.SSID;
            scheduleTempOne.BSSID = movementTempDataTwo.BSSID;
        } else {
            scheduleTempOne.START_TIME = timelinedatabaseinfo_->getTime(movementTempDataOne.TIME_STAMP);
            scheduleTempOne.END_TIME = timelinedatabaseinfo_->getTime(movementTempDataTwo.TIME_STAMP);
            scheduleTempOne.LATITUDE = movementTempDataOne.LATITUDE;
            scheduleTempOne.LONGITUDE = movementTempDataOne.LONGITUDE;
            scheduleTempOne.MOVEMENT_TYPE= movementTempDataOne.MOVEMENT_TYPE;
            scheduleTempOne.SSID = movementTempDataOne.SSID;
            scheduleTempOne.BSSID = movementTempDataOne.BSSID;
        }
        j++;
    } else if (j == 1) {
        if (i ==1) {
            scheduleTempTwo.START_TIME = timelinedatabaseinfo_->getTime(movementTempDataTwo.TIME_STAMP);
            scheduleTempTwo.END_TIME = timelinedatabaseinfo_->getTime(movementTempDataOne.TIME_STAMP);
            scheduleTempTwo.LATITUDE = movementTempDataTwo.LATITUDE;
            scheduleTempTwo.LONGITUDE = movementTempDataTwo.LONGITUDE;
            scheduleTempTwo.MOVEMENT_TYPE= movementTempDataTwo.MOVEMENT_TYPE;
            scheduleTempTwo.SSID = movementTempDataTwo.SSID;
            scheduleTempTwo.BSSID = movementTempDataTwo.BSSID;
        } else {
            scheduleTempTwo.START_TIME = timelinedatabaseinfo_->getTime(movementTempDataOne.TIME_STAMP);
            scheduleTempTwo.END_TIME = timelinedatabaseinfo_->getTime(movementTempDataTwo.TIME_STAMP);
            scheduleTempTwo.LATITUDE = movementTempDataOne.LATITUDE;
            scheduleTempTwo.LONGITUDE = movementTempDataOne.LONGITUDE;
            scheduleTempTwo.MOVEMENT_TYPE= movementTempDataOne.MOVEMENT_TYPE;
            scheduleTempTwo.SSID = movementTempDataOne.SSID;
            scheduleTempTwo.BSSID = movementTempDataOne.BSSID;
        }
        j++;
    } else {
        if (i == 1) {
            scheduleTempThree.START_TIME = timelinedatabaseinfo_->getTime(movementTempDataTwo.TIME_STAMP);
            scheduleTempThree.END_TIME = timelinedatabaseinfo_->getTime(movementTempDataOne.TIME_STAMP);
            scheduleTempThree.LATITUDE = movementTempDataTwo.LATITUDE;
            scheduleTempThree.LONGITUDE = movementTempDataTwo.LONGITUDE;
            scheduleTempThree.MOVEMENT_TYPE= movementTempDataTwo.MOVEMENT_TYPE;
            scheduleTempThree.SSID = movementTempDataTwo.SSID;
            scheduleTempThree.BSSID = movementTempDataTwo.BSSID;
       } else {
            scheduleTempThree.START_TIME = timelinedatabaseinfo_->getTime(movementTempDataOne.TIME_STAMP);
            scheduleTempThree.END_TIME = timelinedatabaseinfo_->getTime(movementTempDataTwo.TIME_STAMP);
            scheduleTempThree.LATITUDE = movementTempDataOne.LATITUDE;
            scheduleTempThree.LONGITUDE = movementTempDataOne.LONGITUDE;
            scheduleTempThree.MOVEMENT_TYPE= movementTempDataOne.MOVEMENT_TYPE;
            scheduleTempThree.SSID = movementTempDataOne.SSID;
            scheduleTempThree.BSSID = movementTempDataOne.BSSID;
        }
        j= 0;
    }
    if (scheduleTempThree.LONGITUDE  == -1000) {
        return 0;
    }
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ScheduleRdbdataInsert:  start to instert");
    if (j == 0) {
        if (scheduleTempOne.END_TIME.tm_mday== (scheduleTempThree.END_TIME.tm_mday + 1)) {
            valuesUpdateFlag_ = 1;
        } else {
            valuesUpdateFlag_ = 0;
        }
        if (scheduleTempOne.MOVEMENT_TYPE != scheduleTempThree.MOVEMENT_TYPE ||
            scheduleTempOne.MOVEMENT_TYPE != scheduleTempTwo.MOVEMENT_TYPE ||
            (GetTimeDiff(scheduleTempThree.END_TIME, scheduleTempThree.START_TIME)) > IGRONE_TIME) {
            if (scheduleTempOne.MOVEMENT_TYPE == TimelineDatabaseInfo::MovementType::TYPE_STILL) {
                ListRdbdataInsert(scheduleTempOne, valuesUpdateFlag_);
                TrigerListDatabaseObserver();
           }
            scheduleValues.PutInt("MOVEMENT_TYPE", scheduleTempOne.MOVEMENT_TYPE);
            scheduleValues.PutDouble("LATITUDE", scheduleTempOne.LATITUDE);
            scheduleValues.PutDouble("LONGITUDE", scheduleTempOne.LONGITUDE);
            scheduleValues.PutInt("STARTTIMEYEAR", scheduleTempOne.START_TIME.tm_year);
            scheduleValues.PutInt("STARTTIMEMONTH", scheduleTempOne.START_TIME.tm_mon);
            scheduleValues.PutInt("STARTTIMEDAY", scheduleTempOne.START_TIME.tm_mday);
            scheduleValues.PutInt("STARTTIMEHOUR", scheduleTempOne.START_TIME.tm_hour);
            scheduleValues.PutInt("STARTTIMEMIN", scheduleTempOne.START_TIME.tm_min);
            scheduleValues.PutInt("STARTTIMESEC", scheduleTempOne.START_TIME.tm_sec);
            scheduleValues.PutInt("ENDTIMEYEAR", scheduleTempOne.END_TIME.tm_year);
            scheduleValues.PutInt("ENDTIMEMONTH", scheduleTempOne.END_TIME.tm_mon);
            scheduleValues.PutInt("ENDTIMEDAY", scheduleTempOne.END_TIME.tm_mday);
            scheduleValues.PutInt("ENDTIMEHOUR", scheduleTempOne.END_TIME.tm_hour);
            scheduleValues.PutInt("ENDTIMEMIN", scheduleTempOne.END_TIME.tm_min);
            scheduleValues.PutInt("ENDTIMESEC", scheduleTempOne.END_TIME.tm_sec);
            scheduleValues.PutString("SSID", scheduleTempOne.SSID);
            scheduleValues.PutString("BSSID", scheduleTempOne.BSSID);
            ret = scheduleStore_->Insert(id, "TIMELINESCHEDULE", scheduleValues);
            if (ret != ERR_OK) {
                return ret;
            }
            if (valuesUpdateFlag_ == 1) {
                DeleteListDatabase(SCHEDULE_TABLE_NAME);
            }
            TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ScheduleRdbdataInsert: insert success");
            // CheckResultSet();
            return ERR_OK;
        }
    } else if (j == 1) {
        if (scheduleTempTwo.END_TIME.tm_mday== (scheduleTempOne.END_TIME.tm_mday+ 1)) {
            valuesUpdateFlag_ = 1;
        } else {
            valuesUpdateFlag_ = 0;
        }
        if (scheduleTempTwo.MOVEMENT_TYPE != scheduleTempOne.MOVEMENT_TYPE ||
            scheduleTempTwo.MOVEMENT_TYPE != scheduleTempThree.MOVEMENT_TYPE ||
            (GetTimeDiff(scheduleTempOne.END_TIME, scheduleTempOne.START_TIME)) > IGRONE_TIME) {
            if (scheduleTempTwo.MOVEMENT_TYPE == TimelineDatabaseInfo::MovementType::TYPE_STILL) {
                ListRdbdataInsert(scheduleTempTwo, valuesUpdateFlag_);
                TrigerListDatabaseObserver();
           }
            scheduleValues.PutInt("MOVEMENT_TYPE", scheduleTempTwo.MOVEMENT_TYPE);
            scheduleValues.PutDouble("LATITUDE", scheduleTempTwo.LATITUDE);
            scheduleValues.PutDouble("LONGITUDE", scheduleTempTwo.LONGITUDE);
            scheduleValues.PutInt("STARTTIMEYEAR", scheduleTempTwo.START_TIME.tm_year);
            scheduleValues.PutInt("STARTTIMEMONTH", scheduleTempTwo.START_TIME.tm_mon);
            scheduleValues.PutInt("STARTTIMEDAY", scheduleTempTwo.START_TIME.tm_mday);
            scheduleValues.PutInt("STARTTIMEHOUR", scheduleTempTwo.START_TIME.tm_hour);
            scheduleValues.PutInt("STARTTIMEMIN", scheduleTempTwo.START_TIME.tm_min);
            scheduleValues.PutInt("STARTTIMESEC", scheduleTempTwo.START_TIME.tm_sec);
            scheduleValues.PutInt("ENDTIMEYEAR", scheduleTempTwo.END_TIME.tm_year);
            scheduleValues.PutInt("ENDTIMEMONTH", scheduleTempTwo.END_TIME.tm_mon);
            scheduleValues.PutInt("ENDTIMEDAY", scheduleTempTwo.END_TIME.tm_mday);
            scheduleValues.PutInt("ENDTIMEHOUR", scheduleTempTwo.END_TIME.tm_hour);
            scheduleValues.PutInt("ENDTIMEMIN", scheduleTempTwo.END_TIME.tm_min);
            scheduleValues.PutInt("ENDTIMESEC", scheduleTempTwo.END_TIME.tm_sec);
            scheduleValues.PutString("SSID", scheduleTempTwo.SSID);
            scheduleValues.PutString("BSSID", scheduleTempTwo.BSSID);
            ret = scheduleStore_->Insert(id, "TIMELINESCHEDULE", scheduleValues);
            if (ret != ERR_OK) {
                TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "ScheduleRdbdataInsert: failed to insert data");
                return ret;
            }
            if (valuesUpdateFlag_ == 1) {
                DeleteListDatabase(SCHEDULE_TABLE_NAME);
            }
            TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ScheduleRdbdataInsert: insert success");
            // CheckResultSet();
            return ERR_OK;
        }
    } else {
        TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "instert scheduleTempThree");
        if (scheduleTempThree.END_TIME.tm_mday== (scheduleTempTwo.END_TIME.tm_mday + 1)) {
            valuesUpdateFlag_ = 1;
        } else {
            valuesUpdateFlag_ = 0;
        }
        if (scheduleTempThree.MOVEMENT_TYPE != scheduleTempTwo.MOVEMENT_TYPE ||
            scheduleTempThree.MOVEMENT_TYPE != scheduleTempOne.MOVEMENT_TYPE ||
           (GetTimeDiff(scheduleTempTwo.END_TIME, scheduleTempTwo.START_TIME)) > IGRONE_TIME) {
           if (scheduleTempThree.MOVEMENT_TYPE == TimelineDatabaseInfo::MovementType::TYPE_STILL) {
                ListRdbdataInsert(scheduleTempThree, valuesUpdateFlag_);
                TrigerListDatabaseObserver();
           }
            scheduleValues.PutInt("MOVEMENT_TYPE", scheduleTempThree.MOVEMENT_TYPE);
            scheduleValues.PutDouble("LATITUDE", scheduleTempThree.LATITUDE);
            scheduleValues.PutDouble("LONGITUDE", scheduleTempThree.LONGITUDE);
            scheduleValues.PutInt("STARTTIMEYEAR", scheduleTempThree.START_TIME.tm_year);
            scheduleValues.PutInt("STARTTIMEMONTH", scheduleTempThree.START_TIME.tm_mon);
            scheduleValues.PutInt("STARTTIMEDAY", scheduleTempThree.START_TIME.tm_mday);
            scheduleValues.PutInt("STARTTIMEHOUR", scheduleTempThree.START_TIME.tm_hour);
            scheduleValues.PutInt("STARTTIMEMIN", scheduleTempThree.START_TIME.tm_min);
            scheduleValues.PutInt("STARTTIMESEC", scheduleTempThree.START_TIME.tm_sec);
            scheduleValues.PutInt("ENDTIMEYEAR", scheduleTempThree.END_TIME.tm_year);
            scheduleValues.PutInt("ENDTIMEMONTH", scheduleTempThree.END_TIME.tm_mon);
            scheduleValues.PutInt("ENDTIMEDAY", scheduleTempThree.END_TIME.tm_mday);
            scheduleValues.PutInt("ENDTIMEHOUR", scheduleTempThree.END_TIME.tm_hour);
            scheduleValues.PutInt("ENDTIMEMIN", scheduleTempThree.END_TIME.tm_min);
            scheduleValues.PutInt("ENDTIMESEC", scheduleTempThree.END_TIME.tm_sec);
            scheduleValues.PutString("SSID", scheduleTempThree.SSID);
            scheduleValues.PutString("BSSID", scheduleTempThree.BSSID);
            ret = scheduleStore_->Insert(id, "TIMELINESCHEDULE", scheduleValues);
            if (ret != ERR_OK) {
                TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "ScheduleRdbdataInsert: failed to insert data");
                return ret;
            }
            if (valuesUpdateFlag_ == 1) {
                DeleteListDatabase(SCHEDULE_TABLE_NAME);
            }
            TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ScheduleRdbdataInsert: insert success");
            // CheckResultSet();
            return ERR_OK;
        }
    }

    if (i==0) {
        i++;
        if (j==0) {
            j = 2;
        } else {
            j--;
        }
    } else {
        i--;
         if (j==0) {
            j = 2;
        } else {
            j--;
        }
    }
     return 0;
}

void TimelineRdbManager::InitListRdbStore()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    int errCode = ERR_OK;
    RdbStoreConfig config(DATABASE_NAME);
    InsertOpenCallback helper;
    listStore_ = RdbHelper::GetRdbStore(config, 1, helper, errCode);

    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "exit");
}

int32_t TimelineRdbManager::ListRdbdataInsert(TimelineDatabaseInfo::Schedule& schedule, int valuesUpdateFlag_)
{
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ListRdbdataInsert: enter");
    ValuesBucket stayValues;
    InitListRdbStore();
    int64_t id;
    int ret = -1;
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ListRdbdataInsert:  start to create table");
    ret = listStore_->ExecuteSql(STAY_CREATE_TABLE);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "ListRdbdataInsert: failed to create table");
        return ret;
    }
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ListRdbdataInsert:  callback sleep wait return");
    stayValues.PutDouble("LATITUDE", schedule.LATITUDE);
    stayValues.PutDouble("LONGITUDE", schedule.LONGITUDE);
    stayValues.PutInt("STARTTIMEYEAR", schedule.START_TIME.tm_year);
    stayValues.PutInt("STARTTIMEMONTH", schedule.START_TIME.tm_mon);
    stayValues.PutInt("STARTTIMEDAY", schedule.START_TIME.tm_mday);
    stayValues.PutInt("STARTTIMEHOUR", schedule.START_TIME.tm_hour);
    stayValues.PutInt("STARTTIMEMIN", schedule.START_TIME.tm_min);
    stayValues.PutInt("STARTTIMESEC", schedule.START_TIME.tm_sec);
    stayValues.PutInt("ENDTIMEYEAR", schedule.END_TIME.tm_year);
    stayValues.PutInt("ENDTIMEMONTH", schedule.END_TIME.tm_mon);
    stayValues.PutInt("ENDTIMEDAY", schedule.END_TIME.tm_mday);
    stayValues.PutInt("ENDTIMEHOUR", schedule.END_TIME.tm_hour);
    stayValues.PutInt("ENDTIMEMIN", schedule.END_TIME.tm_min);
    stayValues.PutInt("ENDTIMESEC", schedule.END_TIME.tm_sec);
    stayValues.PutString("SSID", schedule.SSID);
    stayValues.PutString("BSSID", schedule.BSSID);
    ret = listStore_->Insert(id, "TIMELINELISTTABLE", stayValues);
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ListRdbdataInsert: finish insert TIMELINELISTTABLE");
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "ListRdbdataInsert: failed to insert data");
        return ret;
    }

    if (valuesUpdateFlag_ == 1) {
        DeleteListDatabase(STAY_TABLE_NAME);
    }    

    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ListRdbdataInsert: insert success");
    // CheckResultSet();
    return ERR_OK;
}

int TimelineRdbManager::DeleteListDatabase(std::string tableName)
{
     TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    int columnIndex;
    int intVal;
    int deletedRows;
    std::string str;

    if (store_ == nullptr) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "store_ is not exist");
        sleep(TIMER_SLEEP_TIME);
        InitRdbStore();
        return -1;
    }

    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "test tablename");
    std::unique_ptr<ResultSet> resultSet =
        store_->QuerySql("SELECT * FROM " + tableName + " WHERE ID = (SELECT max(ID) from "+ tableName +") AND ENDTIMEDAY= (schedule.END_TIME.tm_mday -1)");
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "Get table success");
    
    if (resultSet == nullptr) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "database is not exist");
        sleep(TIMER_SLEEP_TIME);
        return -1;
    }
    int ret = resultSet->GoToFirstRow();
    // TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "GoToFirstRow = %{public}d", ret);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "GoToFirstRow wrong");
        sleep(TIMER_SLEEP_TIME);
        return -1;
    }

    ret = resultSet->GetColumnIndex("ID", columnIndex);
    // TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "TrigerDatabaseObserver GetColumnIndex = %{public}d", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckID: GetColumnIndex failed");
        sleep(TIMER_SLEEP_TIME);
        return -1;
    }
    ret = resultSet->GetInt(columnIndex, intVal);
    if (ret != ERR_OK) {
        return -1;
    }
    for (int i =intVal; i > 0; i--) {
        ret = listStore_->Delete(deletedRows, tableName, "ID= ?", std::vector<std::string>{ "i" });
        if (ret != ERR_OK) {
            TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "ListRdbdataInsert: failed to delete data");
            return ret;
        }
    }
    return 1;
}

int TimelineRdbManager::TrigerListDatabaseObserver()
{
    TIMELINE_HILOGI(TIMELINE_MODULE_SERVICE, "enter");
    int columnIndex;
    int intVal;
    double dVal;
    std::string strVal;
    std::string str;

    if (listStore_ == nullptr) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "listStore_ is not exist");
        sleep(TIMER_SLEEP_TIME);
        InitListRdbStore();
        return -1;
    }

    std::unique_ptr<ResultSet> resultSet =
        listStore_->QuerySql("SELECT * FROM TIMELINELISTTABLE WHERE ID = (SELECT max(ID) from TIMELINELISTTABLE)");

    if (resultSet == nullptr) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "database is not exist");
        sleep(TIMER_SLEEP_TIME);
        return -1;
    }

    int ret = resultSet->GoToFirstRow();
    TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "GoToFirstRow = %{public}d", ret);
    if (ret != ERR_OK) {
        sleep(TIMER_SLEEP_TIME);
        return -1;
    }

    ret = resultSet->GetColumnIndex("ID", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckID: GetColumnIndex failed");
        sleep(TIMER_SLEEP_TIME);
        return -1;
    }
    ret = resultSet->GetInt(columnIndex, intVal);
    if (ret != ERR_OK) {
        return -1;
    }

	//get Laitiude
	ret = resultSet->GetColumnIndex("LATITUDE", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckLatitude: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetDouble(columnIndex, dVal);
	latitude_ = dVal;	
    if (ret != ERR_OK) {
        return -1;
    }

	//get Longitude
	ret = resultSet->GetColumnIndex("LONGITUDE", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckLongitude: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetDouble(columnIndex, dVal);
	longitude_ = dVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get StartTimeYear
	ret = resultSet->GetColumnIndex("STARTTIMEYEAR", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckStartTimeYear: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetInt(columnIndex, intVal);
	startTimeYear_ = intVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get StartTimeMonth
	ret = resultSet->GetColumnIndex("STARTTIMEMONTH", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckStartTimeMonth: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetInt(columnIndex, intVal);
	startTimeMonth_ = intVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get StartTimeDay
	ret = resultSet->GetColumnIndex("STARTTIMEDAY", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckStartTimeDay: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetInt(columnIndex, intVal);
	startTimeDay_ = intVal;
    if (ret != ERR_OK) {
        return -1;
    }
	
    //get StartTimeHour
	ret = resultSet->GetColumnIndex("STARTTIMEHOUR", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckStartTimeHour: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetInt(columnIndex, intVal);
	startTimeHour_ = intVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get StartTimeMin
	ret = resultSet->GetColumnIndex("STARTTIMEMIN", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckStartTimeMin: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetInt(columnIndex, intVal);
	startTimeMin_ = intVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get StartTimeSec
	ret = resultSet->GetColumnIndex("STARTTIMESEC", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckStartTimeSec: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetInt(columnIndex, intVal);
	startTimeSec_ = intVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get EndTimeYear
	ret = resultSet->GetColumnIndex("ENDTIMEYEAR", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckEndTimeYear: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetInt(columnIndex, intVal);
	endTimeYear_ = intVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get EndTimeMonth
	ret = resultSet->GetColumnIndex("ENDTIMEMONTH", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckEndTimeMonth: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetInt(columnIndex, intVal);
	endTimeMonth_ = intVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get EndTimeDay
	ret = resultSet->GetColumnIndex("ENDTIMEDAY", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckEndTimeDay: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetInt(columnIndex, intVal);
	endTimeDay_ = intVal;
    if (ret != ERR_OK) {
        return -1;
    }
	
    //get EndTimeHour
	ret = resultSet->GetColumnIndex("ENDTIMEHOUR", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckEndTimeHour: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetInt(columnIndex, intVal);
	endTimeHour_ = intVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get EndTimeMin
	ret = resultSet->GetColumnIndex("ENDTIMEMIN", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckEndTimeMin: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetInt(columnIndex, intVal);
	endTimeMin_ = intVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get EndTimeSec
	ret = resultSet->GetColumnIndex("ENDTIMESEC", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckEndTimeSec: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetInt(columnIndex, intVal);
	endTimeSec_ = intVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get SSID
	ret = resultSet->GetColumnIndex("SSID", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckSSID: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetString(columnIndex, strVal);
	listssid_ = strVal;
    if (ret != ERR_OK) {
        return -1;
    }

    //get BSSID
	ret = resultSet->GetColumnIndex("BSSID", columnIndex);
    if (ret != ERR_OK) {
        TIMELINE_HILOGE(TIMELINE_MODULE_SERVICE, "CheckBSSID: GetColumnIndex failed");
        return -1;
    }
	ret = resultSet->GetString(columnIndex, strVal);
	listbssid_ = strVal;
    if (ret != ERR_OK) {
        return -1;
    }

	ret = resultSet->Close();
    if (ret != ERR_OK) {
        return -1;
    }
    
    listData.LATITUDE = latitude_;
    listData.LONGITUDE = longitude_;
    listData.STARTTIMEYEAR = startTimeYear_;
    listData.STARTTIMEMONTH = startTimeMonth_;
    listData.STARTTIMEDAY = startTimeDay_;
    listData.STARTTIMEHOUR = startTimeHour_;
    listData.STARTTIMEMIN = startTimeMin_;
    listData.STARTTIMESEC = startTimeSec_;
    listData.ENDTIMEYEAR = endTimeYear_;
    listData.ENDTIMEMONTH = endTimeMonth_;
    listData.ENDTIMEDAY = endTimeDay_;
    listData.ENDTIMEHOUR = endTimeHour_;
    listData.ENDTIMEMIN = endTimeMin_;
    listData.ENDTIMESEC = endTimeSec_;
    listData.SSID = listssid_;
    listData.BSSID = listbssid_;

    SaveListData(listData);
	return columnIndex;
}

TimelineDatabaseInfo::ListData TimelineRdbManager::SaveListData(TimelineDatabaseInfo::ListData& listData)
{
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "ENTER");
    listId += 1;
    mutex_.lock();
    listDataMap_.insert(std::make_pair(listId, listData));
    mutex_.unlock();
    return listData;
}

int TimelineRdbManager::GetTimeDiff(tm &startTime, tm &endTime)
{
    int timeDiff;
    if (endTime.tm_min < startTime.tm_min) {
        timeDiff = endTime.tm_min + 60 - startTime.tm_min;
        endTime.tm_hour--;
    } else {
        timeDiff = endTime.tm_min - startTime.tm_min;
    }
    if (endTime.tm_hour < startTime.tm_hour) {
        timeDiff +=(endTime.tm_hour + 24 - startTime.tm_hour)*60;
    } else {
        timeDiff += (endTime.tm_hour - startTime.tm_hour)*60;
    }
    return timeDiff;
}

int InsertOpenCallback::OnCreate(RdbStore &store)
{
    TIMELINE_HILOGD(TIMELINE_MODULE_SERVICE, "OnCreate enter spatial");
    return ERR_OK;
}

int InsertOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
{
    return ERR_OK;
}
}
}